package br.com.afi.web.util.filter;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import br.com.afi.util.log.Logger;

/**
 * Esse filtro verifica se o(s) atributo(s) informado(s) no paramêtro attributes na configuração do
 * filtro (arquivo web.xml) estão na sessão. Se algum destes atributos não estiverem na sessão
 * invalida a sessão e se o paramêtro redirectUrl for informado o filtro realizará o
 * redirecionamento.<br>
 * Exemplo de configuração:<br>
 * <code>
 * 	&lt;filter&gt;<br>
 * 		&lt;filter-name&gt;sessionValidade&lt;/filter-name&gt;<br>
 * 		&lt;filter-class&gt;<br>
 * 			br.com.afi.web.util.filter.SessionValidateFilter<br>
 * 		&lt;/filter-class&gt;<br>
 * 		&lt;init-param&gt;<br>
 * 			&lt;param-name&gt;attributes&lt;/param-name&gt;<br>
 * 			&lt;param-value&gt;user,company&lt;/param-value&gt;<br>
 * 		&lt;/init-param&gt;<br>
 * 		&lt;init-param&gt;<br>
 * 			&lt;param-name&gt;redirectUrl&lt;/param-name&gt;<br>
 * 			&lt;param-value&gt;/home.jsp&lt;/param-value&gt;<br>
 * 		&lt;/init-param&gt;<br>
 * 	&lt;/filter&gt;
 * </code>
 * 
 * @author André de Fontana Ignacio
 * @version 1.0
 */
public class SessionValidateFilter implements Filter
{
	private final Logger log = Logger.getLogger( SessionValidateFilter.class );
	private String name;
	private String redirectUrl;
	private String attributes[];

	@Override
	public void init( FilterConfig filterConfig ) throws ServletException
	{
		this.name = filterConfig.getFilterName();
		final String url = filterConfig.getInitParameter( "redirectUrl" );
		if ( url != null && !url.isEmpty() )
		{
			this.redirectUrl = url;
		}
		final String attributes = filterConfig.getInitParameter( "attributes" );
		if ( attributes == null )
		{
			throw new IllegalArgumentException( "Parâmetro attributes de Inicialização do Filtro " + name + " obrigatório." );
		}
		log.info( "Filtro {0} inicializado. attributes: {1} redirectUrl: {2}", name, attributes, redirectUrl );
		this.attributes = attributes.split( "," );

	}

	@Override
	public void doFilter( ServletRequest servletRequest, ServletResponse res, FilterChain chain ) throws IOException, ServletException
	{
		if ( !validateSession( servletRequest ) )
		{
			final HttpServletRequest req = ( HttpServletRequest ) servletRequest;
			final HttpSession session = req.getSession();
			session.invalidate();
			log.debug( "Atributos não encontrados. Sessão invalidada." );
			if ( redirectUrl != null )
			{
				log.debug( "Redirecionando para {0}", redirectUrl );
				( ( HttpServletResponse ) res ).sendRedirect( req.getContextPath() + redirectUrl );
			}
		}
		else
		{
			chain.doFilter( servletRequest, res );
		}
	}

	@Override
	public void destroy()
	{
		log.info( "Filtro {0} finalizado.", name );
	}

	/**
	 * Método responsável por verificar se a sessão atual do usuário é valida.
	 * 
	 * @param servletRequest ServletRequest.
	 * @return boolean Retorna True caso a sessão seja valida, ou False caso a sessão seja invalida.
	 */
	private boolean validateSession( ServletRequest servletRequest )
	{
		final HttpServletRequest request = ( HttpServletRequest ) servletRequest;
		final HttpSession session = request.getSession();
		for ( String attribute : attributes )
		{
			final Object obj = session.getAttribute( attribute );
			if ( obj == null )
			{
				return false;
			}
		}
		return true;
	}

}
